home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xmlink / xmmlink.c < prev   
C/C++ Source or Header  |  1996-02-07  |  17KB  |  566 lines

  1. /*
  2. # MOTIF-BASED MISSING LINK(tm)
  3. #
  4. #  xmmlink.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /*
  27.   Version 5: 95/10/01 Xt/Motif
  28.   Version 1: 94/08/30 Xt
  29. */
  30.  
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #ifdef VMS
  34. #include <unixlib.h>
  35. #define getlogin cuserid
  36. #else
  37. #ifndef apollo
  38. #include <unistd.h>
  39. #endif
  40. #endif
  41. #include <X11/Intrinsic.h>
  42. #include <X11/StringDefs.h>
  43. #include <X11/Shell.h>
  44. #include <X11/cursorfont.h>
  45. #include <Xm/PanedW.h>
  46. #include <Xm/RowColumn.h>
  47. #include <Xm/Label.h>
  48. #include <Xm/LabelG.h>
  49. #include <Xm/Scale.h>
  50. #include <Xm/ToggleB.h>
  51. #include "Mlink.h"
  52. #include "mlink.xbm"
  53. #include "mouse-l.xbm"
  54. #include "mouse-r.xbm"
  55.  
  56. #ifndef SCOREFILE
  57. #define SCOREFILE "/usr/games/lib/mlink.scores"
  58. #endif
  59.  
  60. /* The following are in MlinksP.h also */
  61. #define MINFACES 1
  62. #define MAXFACES 8
  63. #define MINTILES 1
  64.  
  65. #define MAXTILES 8
  66. #define MAXRECORD 32767
  67.  
  68. static void Initialize();
  69. static void CallbackMlink();
  70.  
  71. static void PrintRecord();
  72. static int HandleSolved();
  73. static void ReadRecords();
  74. static void WriteRecords();
  75.  
  76. static void motif_printf();
  77. static void TileSlider();
  78. static void FaceSlider();
  79. static void OrientToggle();
  80. static void MiddleToggle();
  81.  
  82. static Arg arg[2];
  83. static Widget moves, record, message, mlink, orientSwitch, middleSwitch,
  84.   tile, face;
  85. static int mlinkRecord[2][2][MAXFACES - MINFACES + 1][MAXTILES - MINTILES + 1],
  86.   movesDsp = 0;
  87. static char messageDsp[128] = "Welcome";
  88.  
  89. static void Usage()
  90. {
  91.   (void) fprintf(stderr, "usage: xmmlink\n");
  92.   (void) fprintf(stderr,
  93.     "\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
  94.   (void) fprintf(stderr,
  95.     "\t[-display [{host}]:[{vs}]][-fg {color}] [-bg {color}]\n");
  96.   (void) fprintf(stderr,
  97.     "\t[-mono] [-tile {color}] [-{border|bd} {color}]\n"); 
  98.   (void) fprintf(stderr,
  99.     "\t[-tiles {int}] [-faces {int}] [-[no]orient] [-[no]middle]\n");
  100.   (void) fprintf(stderr,
  101.     "\t[-face{0|1|2|3|4|5|6|7} {color}]\n");
  102.   exit(1);
  103. }
  104.  
  105. static XrmOptionDescRec options[] = {
  106.   {"-fg",        "*mlink.Foreground",    XrmoptionSepArg,    NULL},
  107.   {"-bg",        "*Background",        XrmoptionSepArg,    NULL},
  108.   {"-foreground",    "*mlink.Foreground",    XrmoptionSepArg,    NULL},
  109.   {"-background",    "*Background",        XrmoptionSepArg,    NULL},
  110.   {"-tile",        "*mlink.tileColor",    XrmoptionSepArg,    NULL},
  111.   {"-border",        "*mlink.tileBorder",    XrmoptionSepArg,    NULL},
  112.   {"-bd",        "*mlink.tileBorder",    XrmoptionSepArg,    NULL},
  113.   {"-tiles",        "*mlink.tiles",        XrmoptionSepArg,    NULL},
  114.   {"-faces",        "*mlink.faces",        XrmoptionSepArg,    NULL},
  115.   {"-orient",        "*mlink.orient",    XrmoptionNoArg,        "TRUE"},
  116.   {"-noorient",        "*mlink.orient",    XrmoptionNoArg,        "FALSE"},
  117.   {"-middle",        "*mlink.middle",    XrmoptionNoArg,        "TRUE"},
  118.   {"-nomiddle",        "*mlink.middle",    XrmoptionNoArg,        "FALSE"},
  119.   {"-mono",        "*mlink.mono",        XrmoptionNoArg,        "TRUE"},
  120.   {"-face0",        "*mlink.faceColor0",    XrmoptionSepArg,    NULL},
  121.   {"-face1",        "*mlink.faceColor1",    XrmoptionSepArg,    NULL},
  122.   {"-face2",        "*mlink.faceColor2",    XrmoptionSepArg,    NULL},
  123.   {"-face3",        "*mlink.faceColor3",    XrmoptionSepArg,    NULL},
  124.   {"-face4",        "*mlink.faceColor4",    XrmoptionSepArg,    NULL},
  125.   {"-face5",        "*mlink.faceColor5",    XrmoptionSepArg,    NULL},
  126.   {"-face6",        "*mlink.faceColor6",    XrmoptionSepArg,    NULL},
  127.   {"-face7",        "*mlink.faceColor7",    XrmoptionSepArg,    NULL}
  128. };
  129.  
  130. int main(argc, argv)
  131.   int argc;
  132.   char *argv[];
  133. {
  134.   Widget toplevel; 
  135.   Widget panel, panel2, rowcol, rowcol2, rowcol3;
  136.   Pixmap mouseLeftCursor, mouseRightCursor;
  137.   Pixel fg, bg;
  138.  
  139.   toplevel = XtInitialize(argv[0], "Mlink",
  140.     options, XtNumber(options), &argc, argv);
  141.   if (argc != 1)
  142.     Usage();
  143.  
  144.   XtSetArg(arg[0], XtNiconPixmap,
  145.     XCreateBitmapFromData(XtDisplay(toplevel),
  146.       RootWindowOfScreen(XtScreen(toplevel)),
  147.       (char *) mlink_bits, mlink_width, mlink_height));
  148.   XtSetArg(arg[1], XmNkeyboardFocusPolicy, XmPOINTER); /* not XmEXPLICIT */
  149.   XtSetValues(toplevel, arg, 2);
  150.   panel = XtCreateManagedWidget("panel", xmPanedWindowWidgetClass, toplevel,
  151.     NULL, 0);
  152.   panel2 = XtVaCreateManagedWidget("panel2", xmPanedWindowWidgetClass, panel,
  153.     XmNseparatorOn, False,
  154.     XmNsashWidth, 1,
  155.     XmNsashHeight, 1,
  156.     NULL);
  157.  
  158.   rowcol = XtVaCreateManagedWidget("Rowcol", xmRowColumnWidgetClass, panel2,
  159.     XmNnumColumns, 2,
  160.     XmNorientation, XmHORIZONTAL,
  161.     XmNpacking, XmPACK_COLUMN,
  162.     NULL);
  163.   XtVaGetValues(rowcol, XmNforeground, &fg, XmNbackground, &bg, NULL);
  164.   mouseLeftCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
  165.     RootWindowOfScreen(XtScreen(rowcol)), mouse_left_bits,
  166.     mouse_left_width, mouse_left_height, fg, bg,
  167.     DefaultDepthOfScreen(XtScreen(rowcol)));
  168.   mouseRightCursor = XCreatePixmapFromBitmapData(XtDisplay(rowcol),
  169.     RootWindowOfScreen(XtScreen(rowcol)), mouse_right_bits,
  170.     mouse_right_width, mouse_right_height, fg, bg,
  171.     DefaultDepthOfScreen(XtScreen(rowcol)));
  172.   XtVaCreateManagedWidget("mouseLeftText", xmLabelGadgetClass, rowcol,
  173.     XtVaTypedArg, XmNlabelString, XmRString, "Move tile", 10, NULL);
  174.   XtVaCreateManagedWidget("mouseLeft", xmLabelGadgetClass, rowcol,
  175.     XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseLeftCursor, NULL);
  176.   XtVaCreateManagedWidget("mouseRightText", xmLabelGadgetClass, rowcol,
  177.     XtVaTypedArg, XmNlabelString, XmRString, "Randomize", 10, NULL);
  178.   XtVaCreateManagedWidget("mouseRight", xmLabelGadgetClass, rowcol,
  179.     XmNlabelType, XmPIXMAP, XmNlabelPixmap, mouseRightCursor, NULL);
  180.   XtVaCreateManagedWidget("movesText", xmLabelGadgetClass, rowcol,
  181.     XtVaTypedArg, XmNlabelString, XmRString, "Moves", 6, NULL);
  182.   moves = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
  183.   XtVaCreateManagedWidget("recordText", xmLabelGadgetClass, rowcol,
  184.     XtVaTypedArg, XmNlabelString, XmRString, "Record", 7, NULL);
  185.   record = XtVaCreateManagedWidget("0", xmLabelWidgetClass, rowcol, NULL);
  186.  
  187.   rowcol2 = XtVaCreateManagedWidget("Rowcol2", xmRowColumnWidgetClass, panel2,
  188.     NULL);
  189.   XtVaGetValues(rowcol2, XmNforeground, &fg, XmNbackground, &bg, NULL);
  190.   tile = XtVaCreateManagedWidget("tile", xmScaleWidgetClass, rowcol2,
  191.     XtVaTypedArg, XmNtitleString, XmRString, "Tiles", 6,
  192.     XmNminimum, MINTILES,
  193.     XmNmaximum, MAXTILES,
  194.     XmNvalue, MINTILES,
  195.     XmNshowValue, True,
  196.     XmNorientation, XmHORIZONTAL,
  197.     NULL);
  198.   XtAddCallback(tile, XmNvalueChangedCallback, TileSlider, NULL);
  199.   face = XtVaCreateManagedWidget("face", xmScaleWidgetClass, rowcol2,
  200.     XtVaTypedArg, XmNtitleString, XmRString, "Faces", 6,
  201.     XmNminimum, MINFACES,
  202.     XmNmaximum, MAXFACES,
  203.     XmNvalue, MINFACES,
  204.     XmNshowValue, True,
  205.     XmNorientation, XmHORIZONTAL,
  206.     NULL);
  207.   XtAddCallback(face, XmNvalueChangedCallback, FaceSlider, NULL);
  208.   rowcol3 = XtVaCreateManagedWidget("Rowcol3", xmRowColumnWidgetClass, rowcol2,
  209.     XmNnumColumns, 1,
  210.     XmNorientation, XmHORIZONTAL,
  211.     XmNpacking, XmPACK_COLUMN,
  212.     NULL);
  213.   orientSwitch = XtVaCreateManagedWidget ("Orient",
  214.     xmToggleButtonWidgetClass, rowcol3,
  215.     NULL);
  216.   XtAddCallback(orientSwitch, XmNvalueChangedCallback, OrientToggle, NULL);
  217.   middleSwitch = XtVaCreateManagedWidget ("Middle",
  218.     xmToggleButtonWidgetClass, rowcol3,
  219.     NULL);
  220.   XtAddCallback(middleSwitch, XmNvalueChangedCallback, MiddleToggle, NULL);
  221.   message = XtVaCreateManagedWidget("Play Missing Link! (use mouse and keypad)",
  222.     xmLabelWidgetClass, rowcol2,
  223.     NULL);
  224.  
  225.   mlink = XtCreateManagedWidget("mlink", mlinkWidgetClass, panel,
  226.     NULL, 0);
  227.   XtAddCallback(mlink, XtNselectCallback, CallbackMlink, NULL);
  228.   Initialize(mlink);
  229.   XtRealizeWidget(toplevel);
  230.   XGrabButton(XtDisplay(mlink), AnyButton, AnyModifier, XtWindow(mlink),
  231.     TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
  232.     GrabModeAsync, GrabModeAsync, XtWindow(mlink),
  233.     XCreateFontCursor(XtDisplay(mlink), XC_crosshair));
  234.   XtMainLoop();
  235.  
  236. #ifdef VMS
  237.   return 1;
  238. #else
  239.   return 0;
  240. #endif
  241. }
  242.  
  243. static void Initialize(w)
  244.   Widget w;
  245. {
  246.   int tiles, faces;
  247.   Boolean orient, middle;
  248.  
  249.   XtVaSetValues(w,
  250.     XtNstart, FALSE,
  251.     NULL);
  252.   XtVaGetValues(w,
  253.     XtNtiles, &tiles,
  254.     XtNfaces, &faces,
  255.     XtNorient, &orient,
  256.     XtNmiddle, &middle,
  257.     NULL);
  258.   if (tiles <= MAXTILES)
  259.     XmScaleSetValue(tile, tiles);
  260.   XmScaleSetValue(face, faces);
  261.   XmToggleButtonSetState(orientSwitch, orient, True);
  262.   XmToggleButtonSetState(middleSwitch, middle, True);
  263.   ReadRecords();
  264.   PrintRecord(tiles, faces, orient, middle);
  265. }
  266.  
  267. static void CallbackMlink(w, clientData, callData)
  268.   Widget w;
  269.   caddr_t clientData;
  270.   mlinkCallbackStruct *callData;
  271. {
  272.   int tiles, faces;
  273.   Boolean orient, middle;
  274.  
  275.   XtVaGetValues(w,
  276.     XtNtiles, &tiles,
  277.     XtNfaces, &faces,
  278.     XtNorient, &orient,
  279.     XtNmiddle, &middle,
  280.     NULL);
  281.   (void) strcpy(messageDsp, "");
  282.   switch (callData->reason) {
  283.     case MLINK_RESTORE:
  284.     case MLINK_RESET:
  285.       movesDsp = 0;
  286.       break;
  287.     case MLINK_BLOCKED:
  288.       (void) strcpy(messageDsp, "Blocked");
  289.       break;
  290.     case MLINK_SPACE:
  291.       /*(void) strcpy(messageDsp, "Spaces can't move");*/  /* Too annoying */
  292.       break;
  293.     case MLINK_IGNORE:
  294.       (void) strcpy(messageDsp, "Randomize to start");
  295.       break;
  296.     case MLINK_MOVED:
  297.       movesDsp++;
  298.       XtSetArg(arg[0], XtNstart, TRUE);
  299.       XtSetValues(w, arg, 1);
  300.       break;
  301.     case MLINK_CONTROL:
  302.       return;
  303.     case MLINK_SOLVED:
  304.       if (HandleSolved(movesDsp, tiles, faces, orient, middle))
  305.         (void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
  306.       else
  307.         (void) strcpy(messageDsp, "Solved!");
  308.       XtSetArg(arg[0], XtNstart, FALSE);
  309.       XtSetValues(w, arg, 1);
  310.       break;
  311.     case MLINK_RANDOMIZE:
  312.       movesDsp = 0;
  313.       XtSetArg(arg[0], XtNstart, FALSE);
  314.       XtSetValues(w, arg, 1);
  315.       break;
  316.     case MLINK_ORIENT:
  317.       movesDsp = 0;
  318.       orient = !orient;
  319.       PrintRecord(tiles, faces, orient, middle);
  320.       XtSetArg(arg[0], XtNorient, orient);
  321.       XtSetValues(w, arg, 1);
  322.       XmToggleButtonSetState(orientSwitch, orient, True);
  323.       break;
  324.     case MLINK_MIDDLE:
  325.       movesDsp = 0;
  326.       middle = !middle;
  327.       PrintRecord(tiles, faces, orient, middle);
  328.       XtSetArg(arg[0], XtNmiddle, middle);
  329.       XtSetValues(w, arg, 1);
  330.       XmToggleButtonSetState(middleSwitch, middle, True);
  331.       break;
  332.     case MLINK_DEC_X:
  333.       movesDsp = 0;
  334.       tiles--;
  335.       PrintRecord(tiles, faces, orient, middle);
  336.       XtSetArg(arg[0], XtNtiles, tiles);
  337.       XtSetValues(w, arg, 1);
  338.       if (tiles <= MAXTILES)
  339.         XmScaleSetValue(tile, tiles);
  340.       break;
  341.     case MLINK_INC_X:
  342.       movesDsp = 0;
  343.       tiles++;
  344.       PrintRecord(tiles, faces, orient, middle);
  345.       XtSetArg(arg[0], XtNtiles, tiles);
  346.       XtSetValues(w, arg, 1);
  347.       if (tiles <= MAXTILES)
  348.         XmScaleSetValue(tile, tiles);
  349.       break;
  350.     case MLINK_DEC_Y:
  351.       movesDsp = 0;
  352.       faces--;
  353.       PrintRecord(tiles, faces, orient, middle);
  354.       XtSetArg(arg[0], XtNfaces, faces);
  355.       XtSetValues(w, arg, 1);
  356.       XmScaleSetValue(face, faces);
  357.       break;
  358.     case MLINK_INC_Y:
  359.       movesDsp = 0;
  360.       faces++;
  361.       PrintRecord(tiles, faces, orient, middle);
  362.       XtSetArg(arg[0], XtNfaces, faces);
  363.       XtSetValues(w, arg, 1);
  364.       XmScaleSetValue(face, faces);
  365.       break;
  366.     case MLINK_COMPUTED:
  367.       XtSetArg(arg[0], XtNstart, FALSE);
  368.       XtSetValues(w, arg, 1);
  369.       break;
  370.     case MLINK_UNDO:
  371.       movesDsp--;
  372.       XtSetArg(arg[0], XtNstart, TRUE);
  373.       XtSetValues(w, arg, 1);
  374.       break;
  375.   }
  376.   motif_printf(message, "%s", messageDsp);
  377.   motif_printf(moves, "%d", movesDsp);
  378. }
  379.  
  380. static void TileSlider(w, clientData, cbs)
  381.   Widget w;
  382.   XtPointer clientData;
  383.   XmScaleCallbackStruct *cbs;
  384. {
  385.   int tiles = cbs->value, faces, old;
  386.  
  387.   XtVaGetValues(mlink,
  388.     XtNtiles, &old,
  389.     XtNfaces, &faces,
  390.     NULL);
  391.   if (old != tiles) {
  392.     XtVaSetValues(mlink,
  393.       XtNtiles, tiles,
  394.       NULL);
  395.     movesDsp = 0;
  396.     motif_printf(moves, "%d", movesDsp);
  397.     PrintRecord(tiles, faces, XmToggleButtonGetState(orientSwitch),
  398.       XmToggleButtonGetState(middleSwitch));
  399.   }
  400. }
  401.  
  402. static void FaceSlider(w, clientData, cbs)
  403.   Widget w;
  404.   XtPointer clientData;
  405.   XmScaleCallbackStruct *cbs;
  406. {
  407.   int tiles, faces = cbs->value, old;
  408.  
  409.   XtVaGetValues(mlink,
  410.     XtNtiles, &tiles,
  411.     XtNfaces, &old,
  412.     NULL);
  413.   if (old != faces) {
  414.     XtVaSetValues(mlink,
  415.       XtNfaces, faces,
  416.       NULL);
  417.     movesDsp = 0;
  418.     motif_printf(moves, "%d", movesDsp);
  419.     PrintRecord(tiles, faces, XmToggleButtonGetState(orientSwitch),
  420.       XmToggleButtonGetState(middleSwitch));
  421.   }
  422. }
  423.  
  424. static void OrientToggle(w, clientData, cbs)
  425.   Widget w;
  426.   XtPointer clientData;
  427.   XmToggleButtonCallbackStruct *cbs;
  428. {
  429.   int tiles, faces;
  430.   Boolean orient = cbs->set;
  431.  
  432.   XtVaSetValues(mlink,
  433.     XtNorient, orient,
  434.     NULL);
  435.   XtVaGetValues(mlink,
  436.     XtNtiles, &tiles,
  437.     XtNfaces, &faces,
  438.     NULL);
  439.   movesDsp = 0;
  440.   motif_printf(moves, "%d", movesDsp);
  441.   PrintRecord(tiles, faces, orient, XmToggleButtonGetState(middleSwitch));
  442. }
  443.  
  444. static void MiddleToggle(w, clientData, cbs)
  445.   Widget w;
  446.   XtPointer clientData;
  447.   XmToggleButtonCallbackStruct *cbs;
  448. {
  449.   int tiles, faces;
  450.   Boolean middle = cbs->set;
  451.  
  452.   XtVaSetValues(mlink,
  453.     XtNmiddle, middle,
  454.     NULL);
  455.   XtVaGetValues(mlink,
  456.     XtNtiles, &tiles,
  457.     XtNfaces, &faces,
  458.     NULL);
  459.   movesDsp = 0;
  460.   motif_printf(moves, "%d", movesDsp);
  461.   PrintRecord(tiles, faces, XmToggleButtonGetState(orientSwitch), middle);
  462. }
  463.  
  464. static void PrintRecord(tiles, faces, orient, middle)
  465.   int tiles, faces;
  466.   Boolean orient, middle;
  467. {
  468.   int i = tiles - MINTILES, j = faces - MINFACES;
  469.   int k = (orient) ? 1 : 0, l = (middle) ? 1 : 0;
  470.  
  471.   if (tiles > MAXTILES)
  472.     motif_printf(record, "NOT RECORDED");
  473.   else if (mlinkRecord[l][k][j][i] >= MAXRECORD)
  474.     motif_printf(record, "NEVER");
  475.   else
  476.     motif_printf(record, "%d", mlinkRecord[l][k][j][i]);
  477. }
  478.  
  479. static int HandleSolved(counter, tiles, faces, orient, middle)
  480.   int counter, tiles, faces;
  481.   Boolean orient, middle;
  482. {
  483.   int i = tiles - MINTILES, j = faces - MINFACES;
  484.   int k = (orient) ? 1 : 0, l = (middle) ? 1 : 0;
  485.  
  486.   if (tiles <= MAXTILES && counter < mlinkRecord[l][k][j][i]) {
  487.     mlinkRecord[l][k][j][i] = counter;
  488.     if (tiles < 4 || faces < 2)
  489.       mlinkRecord[!l][k][j][i] = counter;
  490.     WriteRecords();
  491.     PrintRecord(tiles, faces, orient, middle);
  492.     return TRUE;
  493.   }
  494.   return FALSE;
  495. }
  496.  
  497. static void ReadRecords()
  498. {
  499.   FILE *fp;
  500.   int i, j, k, l, n;
  501.  
  502.   for (l = 0; l < 2; l++)
  503.     for (k = 0; k < 2; k++)
  504.       for (j = 0; j < MAXFACES - MINFACES + 1; j++)
  505.         for (i = 0; i < MAXTILES - MINTILES + 1; i++)
  506.           mlinkRecord[l][k][j][i] = MAXRECORD;
  507.   if ((fp = fopen(SCOREFILE, "r")) == NULL)
  508.     motif_printf(messageDsp, "Can not open %s, taking defaults.", SCOREFILE);
  509.   else {
  510.     for (l = 0; l < 2; l++)
  511.       for (k = 0; k < 2; k++)
  512.         for (j = 0; j < MAXFACES - MINFACES + 1; j++)
  513.           for (i = 0; i < MAXTILES - MINTILES + 1; i++) {
  514.             (void) fscanf(fp, "%d", &n);
  515.             mlinkRecord[l][k][j][i] = n;
  516.       }
  517.     (void) fclose(fp);
  518.   }
  519. }
  520.  
  521. static void WriteRecords()
  522. {
  523.   FILE *fp;
  524.   int i, j, k, l;
  525.  
  526.   if ((fp = fopen(SCOREFILE, "w")) == NULL)
  527.     motif_printf(messageDsp, "Can not write to %s.", SCOREFILE);
  528.   else {
  529.     for (l = 0; l < 2; l++) {
  530.       for (k = 0; k < 2; k++) {
  531.         for (j = 0; j < MAXFACES - MINFACES + 1; j++) {
  532.           for (i = 0; i < MAXTILES - MINTILES + 1; i++)
  533.             (void) fprintf(fp, "%d ", mlinkRecord[l][k][j][i]);
  534.           (void) fprintf(fp, "\n");
  535.         }
  536.         (void) fprintf(fp, "\n");
  537.       }
  538.       (void) fprintf(fp, "\n");
  539.     }
  540.     (void) fclose(fp);
  541.   }
  542. }
  543.  
  544. #include <varargs.h>
  545. static void motif_printf(va_alist)
  546.   va_dcl
  547. {
  548.   Widget w;
  549.   char *format;
  550.   va_list args;
  551.   char str[1000];
  552.   Arg wargs[10];
  553.   XmString xmstr;
  554.  
  555.   va_start(args);
  556.   w = va_arg(args, Widget);
  557.   if (!XtIsSubclass(w, xmLabelWidgetClass))
  558.     XtError("motif_printf() requires a Label Widget");
  559.   format = va_arg(args, char *);
  560.   (void) vsprintf(str, format, args);
  561.   xmstr = XmStringCreateLtoR(str, XmSTRING_DEFAULT_CHARSET);
  562.   XtSetArg(wargs[0], XmNlabelString, xmstr);
  563.   XtSetValues(w, wargs, 1);
  564.   va_end(args);
  565. }
  566.